package com.gy.boot.common.util;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * ZIP文件打包下载工具
 * */
public class ZipDownloadUtil {

    private static final String ZIP_SUFFIX = ".zip";
    private static final String DEFAULT_ZIP_NAME = "DownloadZip.zip";

    public static void toZip(HttpServletResponse response, String[] filePaths) throws IOException {
        toZip(response, filePaths, DEFAULT_ZIP_NAME);
    }
    /**
     * 直接下载文件, 文件流下载
     * @param filePaths 需要压缩的文件
     * @param zipFilename 文件下载名
     * */
    public static void toZip(HttpServletResponse response, String[] filePaths, String zipFilename) throws IOException {
        zipFilename = BlankUtil.isBlank(zipFilename) ? DEFAULT_ZIP_NAME : zipFilename;
        zipFilename = zipFilename.endsWith(ZIP_SUFFIX) ? zipFilename : (zipFilename + ZIP_SUFFIX);
        response.setContentType("application/octet-stream; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename="+zipFilename);
        toZip(filePaths, response.getOutputStream());
    }
    /**
     * 压缩成ZIP
     * @param filePaths 需要压缩的文件路径列表
     * @param outputStream 压缩文件输出流
     * */
    private static void toZip(String[] filePaths, ServletOutputStream outputStream) throws IOException {
        if (BlankUtil.isBlank(filePaths)) {
            return;
        }
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        System.out.println("==== 文件ZIP压缩开始 ====");
        for (String filePath : filePaths) {
            // 文件路径为NULL,跳过
            if (BlankUtil.isBlank(filePath)) { continue; }
            // 获取打包文件, 文件不存在,跳过
            File file = new File(filePath);
            if (!file.exists()) {
                System.out.println(filePath + " 不存在");
                continue;
            }
            if (file.isDirectory()) {
                System.out.println(filePath + " 读取目录");
                zipReadFileDir(zipOutputStream, file);
                continue;
            }
            // 读写文件内容
            zipReadFile(zipOutputStream, file);
            System.out.println(filePath + " 读取写入ZIP完成");
        }
        zipOutputStream.close();
        outputStream.close();
        System.out.println("==== 文件ZIP压缩完成 ====");
    }
    /**
     * 读取目录
     * */
    private static void zipReadFileDir(ZipOutputStream zipOutputStream, File fileDir) throws IOException {
        File[] files = fileDir.listFiles();
        if (files == null || files.length == 0) { return; }
        for (File file : files) {
            if (!file.exists()) { continue; }
            if (file.isDirectory()) {
                zipReadFileDir(zipOutputStream, file);
                continue;
            }
            zipReadFile(zipOutputStream, file);
        }
    }
    /**
     * 读取文件
     * */
    private static void zipReadFile(ZipOutputStream zipOutputStream, File file) throws IOException {
        // 读写文件内容
        byte[] buf = new byte[1024];
        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
        int len;
        FileInputStream fileInputStream = new FileInputStream(file);
        while ((len = fileInputStream.read(buf)) != -1) {
            zipOutputStream.write(buf, 0, len);
        }
        zipOutputStream.closeEntry();
        fileInputStream.close();
    }

}
